#define __LIBRARY__ // 使用了_syscalln

#include <shm.h>    //使用了shm_t
#include <stdio.h>  //使用了printf()
#include <sem.h>    //信号量的头文件
#include <unistd.h> //用到了 __NR_xxx
#include <stdlib.h> //使用了fflush
/* 信号量系统调用 */
_syscall2(sem_t *, sem_open, const char *, name, unsigned int, value);
_syscall1(int, sem_wait, sem_t *, sem);
_syscall1(int, sem_post, sem_t *, sem);
_syscall1(int, sem_unlink, const char *, name);
/* 共享内存的系统调用 */
_syscall2(int, shmget, key_t, key, size_t, size);
_syscall1(void *, shmat, int, shmid);

#define BUFSIZE 10  // 缓冲区大小
#define MAX_NUM 500 // 为了测试方便，item_num最大为500

#define KEY 1024 // 用于为共享内存段命名

sem_t *empty, *full, *mutex;

void producer(int *p)
{
    // 生产一个产品 item；
    int item_num;

    printf("I am a producer, here are contents of producing:\n");
    fflush(stdout);

    for (item_num = 0; item_num <= MAX_NUM; item_num++)
    {
        // test是否有空闲的缓存资源
        sem_wait(empty);
        // 通过互斥信号量，实现互斥访问
        sem_wait(mutex);
        /* 将item放到空闲缓存中 */
        *(p + item_num % BUFSIZE) = item_num;
        printf("%d\n", item_num);
        fflush(stdout);

        sem_post(mutex);
        // 增加产品资源
        sem_post(full);
    }
    printf("Producer, over.\n");
}

int main()
{
    long key = KEY;
    int shmid;
    int *p;
    int i;
    /* 为了防止已经open了如下信号量，先释放*/
    sem_unlink("empty");
    sem_unlink("full");
    sem_unlink("mutex");
    /* 创建信号量 */

    empty = sem_open("empty", BUFSIZE);
    full = sem_open("full", 0);
    mutex = sem_open("mutex", 1);
    
    /* 使用共享内存作为缓冲区 */
    shmid = shmget(key, (MAX_NUM + 1) * sizeof(int));
    p = (int *)shmat(shmid);
    /* 生产者 */
    producer(p);

    return 0;
}
